package com.lc.fbtp.draftmsg.core.parse.electric;

import java.io.UnsupportedEncodingException;
import java.text.MessageFormat;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.lc.fbtp.draftmsg.api.electric.common.Document;
import com.lc.fbtp.draftmsg.api.electric.common.DraftInfo;
import com.lc.fbtp.draftmsg.api.electric.common.MainBody;
import com.lc.fbtp.draftmsg.api.electric.common.MsgHeader;
import com.lc.fbtp.draftmsg.core.parse.exception.IllegalMessageException;

public class ElectricParser {

	private static Logger logger = LoggerFactory.getLogger(ElectricParser.class);
	private static ElectricParser draftParser = null;
	private ElectricParser(){
		
	}
	
	public static ElectricParser getInstance(){
		if(draftParser == null) {
			draftParser = new ElectricParser();
		}
		return draftParser;
	}
	
	@SuppressWarnings("unchecked")
	public DraftInfo parse(byte[] msg){
		DraftInfo draftInfo = new DraftInfo();
		MsgHeader header = new MsgHeader();
		byte[] beginFlagArray = new byte[3];
		byte[] versionIdArray = new byte[3];
		byte[] senderIdArray = new byte[6];
		byte[] receiverIdArray = new byte[6];
		byte[] origSenderArray = new byte[6];
		byte[] origReceiverArray = new byte[6];
		byte[] origSendDateArray = new byte[8];
		byte[] origSendTimeArray = new byte[6];
		byte[] mesgTypeArray = new byte[20];
		byte[] mesgIdArray = new byte[20];
		byte[] mesgRefIdArray = new byte[20];
		byte[] mesgDirectionArray = new byte[1];
		byte[] mesgPriorityArray = new byte[1];
		byte[] encryptFlagArray = new byte[1];
		byte[] bodyLengthArray = new byte[8];
		byte[] bodyChksumArray = new byte[64];
		byte[] reserveArray = new byte[9];
		byte[] endFlagArray = new byte[3];

		System.arraycopy(msg, 0, beginFlagArray, 0, 3);
		System.arraycopy(msg, 3, versionIdArray, 0, 3);
		System.arraycopy(msg, 6, senderIdArray, 0, 6);
		System.arraycopy(msg, 12, receiverIdArray, 0, 6);
		System.arraycopy(msg, 18, origSenderArray, 0, 6);
		System.arraycopy(msg, 24, origReceiverArray, 0, 6);
		System.arraycopy(msg, 30, origSendDateArray, 0, 8);
		System.arraycopy(msg, 38, origSendTimeArray, 0, 6);
		System.arraycopy(msg, 44, mesgTypeArray, 0, 20);
		System.arraycopy(msg, 64, mesgIdArray, 0, 20);
		System.arraycopy(msg, 84, mesgRefIdArray, 0, 20);
		System.arraycopy(msg, 104, mesgDirectionArray, 0, 1);
		System.arraycopy(msg, 105, mesgPriorityArray, 0, 1);
		System.arraycopy(msg, 106, encryptFlagArray, 0, 1);
		System.arraycopy(msg, 107, bodyLengthArray, 0, 8);
		System.arraycopy(msg, 115, bodyChksumArray, 0, 64);
		System.arraycopy(msg, 179, reserveArray, 0, 9);
		System.arraycopy(msg, 188, endFlagArray, 0, 3);
		try {
			header.setBeginFlag(new String(beginFlagArray, "UTF-8"));
			header.setBodyChksum(new String(bodyChksumArray, "UTF-8"));
			header.setBodyLength(new String(bodyLengthArray, "UTF-8"));
			header.setEncryptFlag(new String(encryptFlagArray, "UTF-8"));
			header.setEndFlag(new String(endFlagArray, "UTF-8"));
		//	header.setMesgDirection(new String(mesgDirectionArray, "UTF-8"));
			header.setMesgId(new String(mesgIdArray, "UTF-8"));
			header.setMesgPriority(new String(mesgPriorityArray, "UTF-8"));
			header.setMesgRefId(new String(mesgRefIdArray, "UTF-8"));
			header.setMesgType(new String(mesgTypeArray, "UTF-8").trim());
			header.setOrigReceiver(new String(origReceiverArray, "UTF-8"));
			header.setOrigSendDate(new String(origSendDateArray, "UTF-8"));
			header.setOrigSender(new String(origSenderArray, "UTF-8"));
			header.setOrigSendTime(new String(origSendTimeArray, "UTF-8"));
			header.setReceiverId(new String(receiverIdArray, "UTF-8"));
			header.setReserve(new String(reserveArray, "UTF-8").trim());
			header.setSenderId(new String(senderIdArray, "UTF-8"));
			header.setVersionId(new String(versionIdArray, "UTF-8"));
			draftInfo.setMsgHeader(header);
		} catch (UnsupportedEncodingException e) {
			//TODO 日志形式输出
			logger.error("报文字符集错误");
			throw new IllegalMessageException();
		}
		Integer bodyLength = Integer.parseInt(header.getBodyLength());
		byte[] documentArray = new byte[Integer.parseInt(header.getBodyLength())];
		String msgBodyStr = "";
		System.arraycopy(msg, 191, documentArray, 0, bodyLength);
		try {
			msgBodyStr = new String(documentArray, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
//		String encryStr = SHA256.encry(document);
//		if(!encryStr.equals(header.getBodyChksum())){
//			logger.error("报文体SHA-256加密结果为[{}],报文校验和为[{}],不匹配", new Object[]{encryStr, header.getBodyChksum()});
//			throw new IllegalBodyChksumException("报文校验和不匹配");
//		}
		String mesgType = header.getMesgType();
		String[] mesgTypeInfo = mesgType.split("\\.", -1);
		String classNameTemplate = "com.lc.draft.msg.beans.{0}.{1}{2}.{3}{4}";
		String className = MessageFormat.format(classNameTemplate, mesgTypeInfo[0].toLowerCase(),mesgTypeInfo[0].toLowerCase(),mesgTypeInfo[1],mesgTypeInfo[0], mesgTypeInfo[1]);
		Class<? extends MainBody> clazz = null;
		try {
			clazz = (Class<? extends MainBody>) Class.forName(className);
			BodyParseResult result = DocumentParser.getInstance().parse(msgBodyStr, clazz);
			Document doc = result.getDocument();
			draftInfo.setMsgBody(doc);
			draftInfo.setMsgBodyStr(msgBodyStr);
			draftInfo.setMainBodyStr(result.getMainBodyXmlStr());
			draftInfo.setDraftNo(mesgTypeInfo[0]+mesgTypeInfo[1]);
			draftInfo.setDtTm(doc.getMainBody().getDtTm());
			draftInfo.setId(doc.getMainBody().getId());
			draftInfo.setOriginId(doc.getMainBody().getOrgnlId());
			draftInfo.setPtcptSgntr(doc.getPtcptSgntr());
			draftInfo.setCntrlBkSgntr(doc.getCntrlBkSgntr());
		} catch (Exception e) {
			logger.error("报文解析失败", e);
		}
		return draftInfo;
	}
	
}
